/*
 * Copyright 2008 the Breachwalls OSS project and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.breachwalls.mogen.generator.template;

import java.io.File;

import com.breachwalls.mogen.model.DomainModelSpec;
import com.breachwalls.mogen.model.Model;
import com.breachwalls.mogen.model.ModelProperty;
import com.breachwalls.mogen.utils.JavaNameUtils;

/**
 * Freemarkerのテンプレートを使用したドメインモデルテンプレート.
 * @author todoken
 * @version $Revision: 31 $
 */
public class FreeMarkerDomainModelTemplate extends ModelTemplateSupport {

    /**
     * シリアルバージョンID.
     */
    private static final long serialVersionUID = 1L;

    /**
     * コンストラクタ.
     * @param base ファイル出力先ベースディレクトリ
     * @param model 自動生成するモデルの情報
     */
    public FreeMarkerDomainModelTemplate(final File base, final Model model) {
        super(base, model);
        addGenerateFile(model.getShortClassName() + ".java", "domain/domain.ftl");
    }

    /**
     * モデルプロパティから、このエンティティのフィールドメソッド名を取得する.
     * @param property モデルプロパティ
     * @return エンティティフィールドメソッド名
     */
    public String getMethodName(ModelProperty property) {
        String name = property.getName();
        return JavaNameUtils.toJavaMethodName(name);
    }

    /**
     * プロパティがコレクション型の場合のフィールド名を取得する.
     * @param property モデルプロパティ
     * @return コレクション型のときのフィールド名
     */
    public String getCollectionFieldName(ModelProperty property) {
        String name = property.getName();
        return JavaNameUtils.toCollectionFieldName(name);
    }

    /**
     * プロパティがコレクション型の場合のメソッド名を取得する.
     * @param property モデルプロパティ
     * @return コレクション型のときのメソッド名
     */
    public String getCollectionMethodName(ModelProperty property) {
        String name = getCollectionFieldName(property);
        return JavaNameUtils.toJavaMethodName(name);
    }

    /**
     * プロパティのスペックを取得し、指定したスペックを持っているかをチェックする.
     * @param specs モデルプロパティに設定されている全てのスペック
     * @param expect 含まれているか確認するスペック
     * @return 確認するスペックが含まれている場合はTRUEを返す
     */
    protected boolean hasSpec(String[] specs, DomainModelSpec expect) {
        if (specs != null) {
            for (String spec : specs) {
                DomainModelSpec type = DomainModelSpec.valueOf(spec);
                if (expect == type) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * プロパティがリストのスペックかをチェックする.
     * @param property モデルのプロパティ
     * @return プロパティがリストスペックである場合はTRUEを返す
     */
    public boolean isList(ModelProperty property) {
        String[] specs = property.getSpecs();
        return hasSpec(specs, DomainModelSpec.LIST);
    }

    /**
     * プロパティがセットのスペックかをチェックする.
     * @param property モデルのプロパティ
     * @return プロパティがセットのスペックである場合はTRUEを返す
     */
    public boolean isSet(ModelProperty property) {
        String[] specs = property.getSpecs();
        return hasSpec(specs, DomainModelSpec.SET);
    }

}
